/**
 * This file is Copyright © 2008 Software Craftsmen Limited. All Rights Reserved.
 */
package com.softwarecraftsmen.orogeny.execution;

import com.softwarecraftsmen.orogeny.buildLogs.Indentation;
import com.softwarecraftsmen.orogeny.buildLogs.IndentingBuildLog;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

import java.io.PrintWriter;
import java.io.StringWriter;

public abstract class SuccessOrFailure
{
	public abstract void writeToLog(final @NotNull IndentingBuildLog buildLog, final @NotNull Indentation indentation);

	public abstract boolean isSuccess();

	public abstract boolean isFailure();

	@NotNull
	public static SuccessOrFailure Success = new SuccessOrFailure()
	{
		@NonNls
		private static final String Message = "succeeded";

		public void writeToLog(final @NotNull IndentingBuildLog buildLog, final @NotNull Indentation indentation)
		{
			buildLog.writeMessage(indentation, Message);
		}

		public boolean isSuccess()
		{
			return true;
		}

		public boolean isFailure()
		{
			return false;
		}

		@NotNull
		public String toString()
		{
			return Message;
		}
	};

	public static SuccessOrFailure Failure(final @NotNull Throwable throwable)
	{
		return Throwable(throwable);
	}

	public static SuccessOrFailure Failure(final @NotNull String message)
	{
		return new SuccessOrFailure()
		{
			public void writeToLog(final @NotNull IndentingBuildLog buildLog, final @NotNull Indentation indentation)
			{
				buildLog.writeMessage(indentation, message());
			}

			public boolean isSuccess()
			{
				return false;
			}

			public boolean isFailure()
			{
				return true;
			}

			@NotNull
			public String toString()
			{
				return message();
			}

			private String message()
			{
				return "failed: " + message;
			}
		};
	}

	public static SuccessOrFailure Throwable(final @NotNull Throwable throwable)
	{
		return new SuccessOrFailure()
		{
			public void writeToLog(final @NotNull IndentingBuildLog buildLog, final @NotNull Indentation indentation)
			{
				buildLog.writeMessage(indentation, message());
			}

			public boolean isSuccess()
			{
				return false;
			}

			public boolean isFailure()
			{
				return true;
			}

			@NotNull
			public String toString()
			{
				return message();
			}

			private String message()
			{
				final StringWriter writer = new StringWriter();
				writer.write("failed: ");
				writer.write(throwable.getMessage());
                final PrintWriter printWriter = new PrintWriter(writer);
                throwable.printStackTrace(printWriter);
                printWriter.flush();
				return writer.toString();
			}
		};
	}
}
